let fib = x => {
    if (x <= 2) {
        return 1
    } else {
        return fib(x - 1) + fib(x - 2)
    }
}

let foo = (fib1, x) => {
    if (x <= 2) {
        return 1
    } else {
        return fib1(fib1, x - 1) + fib1(fib1, x - 2)
    }
}

// But, notice what’s happened: if we pass the factorial function to f,
// it will return the factorial function. The factorial function is thus a fixed point of f,
// and can be determined using the Y combinator. So how do we get there?
// 传入 fib1 其实返回的也是一个 fib1 函数
// f(x) = x
// foo1(fib1) = fib1 所以说 fib1 就是 foo 的一个不动点 ？？
let foo1 =
    fib1 => {
        return x => {
            if (x <= 2) {
                return 1
            } else {
                return fib1(fib1)(x - 1) + fib1(fib1)(x - 2)
            }
        }
    };

let foo2 =
    fib1 => {
        return x => {
            let f = (q, x) => {
                if (x <= 2) {
                    return 1
                } else {
                    return q(x - 1) + q(x - 2)
                }
            }
            return f(
                fib1(fib1), x
            )
        }
    };

let foo3 =
    fib1 => {
        return x => {
            let f = (q) => {
                return x => {
                    if (x <= 2) {
                        return 1
                    } else {
                        return q(x - 1) + q(x - 2)
                    }
                }
            };
            return f(
                fib1(fib1),
            )(x)
        }
    };

// 然后这里的 f 可以独立出来
let f = q => {
    return x => {
        if (x <= 2) {
            return 1
        } else {
            return q(x - 1) + q(x - 2)
        }
    }
};

// this is Y
let foo4 =
    fib1 => {
        return x => {
            return f(fib1(fib1))(x)
        }
    };

let myY = f => {

    let g =
        h => {
            return x => {
                return f(h(h))(x)
            }
        };

    return g(g)
};

// f(Y(f)) = Y(f)

// let Y = function (f) {
//     let g = function (h) {
//         return function (x) {
//             return f(h(h))(x);
//         }
//     };
//     return g(g)
// }
// var factorial = Y(function (recurse) {
//     return function (x) {
//         return x == 0 ? 1 : x * recurse(x - 1);
//     };
// })

let fibY = myY(f)

console.dir(fibY(5));
